package cc.rengu.redp.flowable.service.impl;

import cc.rengu.redp.flowable.service.WorkFlowVar;
import lombok.Getter;
import lombok.Setter;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

/**
 * 差错处理流程变量基础类
 * @author xushitang 2017年2月14日 下午6:16:40
 *
 */
@Getter
@Setter
public abstract class WorkFlowVarBase implements WorkFlowVar {

	public static final String INIT_FLOW_STATUS = "S00";

	protected String flowStatus;               //当前流程状态
	
	/**
	 * 构造方法
	 */
	protected WorkFlowVarBase(){
		//nothing should be done.
	}
	
	/**
	 * 构造方法：用Map初始化流程变量
	 * @param tmpMap
	 */
	protected WorkFlowVarBase(Map<String, Object> tmpMap) {
		 setVarMap(tmpMap);
	}
	
	/**
	 * 设置本类的参数
	 * @param tmpMap
	 */
	@Override
	public void setVarMap(Map<String, Object> tmpMap){
		for (Field field : this.getClass().getDeclaredFields()){
			fieldSet(tmpMap, field);
		}
		
		for (Field field : this.getClass().getSuperclass().getDeclaredFields()){
			fieldSet(tmpMap, field);
		}
	}

	/**
	 * 获取流程变量组
	 * @return 返回Map的流程变量
	 */
	@Override
	public Map<String, Object> getVarMap(){
		Map<String, Object> tmpMap = new HashMap<String, Object>();
		
		for (Field field : this.getClass().getDeclaredFields()){
			fieldGet(tmpMap, field);
		}
		
		for (Field field : this.getClass().getSuperclass().getDeclaredFields()){
			fieldGet(tmpMap, field);
		}
		
		return tmpMap;
	}

	/**
	 * 从Map获取变量
	 * @param tmpMap
	 * @param field
	 */
	private void fieldGet(Map<String, Object> tmpMap, Field field) {
		if (Modifier.isStatic(field.getModifiers())){
			return;
		}
		field.setAccessible(true);
		try {
			Object filedData = field.get(this);
			if (filedData != null){
				tmpMap.put(field.getName(), filedData);
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 保存变量到Map
	 * @param tmpMap
	 * @param field
	 */
	private void fieldSet(Map<String, Object> tmpMap, Field field) {
		if (Modifier.isStatic(field.getModifiers())){
			return;
		}
		if (tmpMap.containsKey(field.getName())){
			field.setAccessible(true);
			try {
				field.set(this, String.valueOf(tmpMap.get(field.getName().trim())));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
	}
}
